home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / gst-0.10 / gst / extend / leveller.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  7.9 KB  |  234 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import os
  5. import sys
  6. import math
  7. import gobject
  8. import pygst
  9. pygst.require('0.10')
  10. import gst
  11. import utils
  12. from pygobject import gsignal
  13. import sources
  14. from sources import EOS, ERROR, UNKNOWN_TYPE, WRONG_TYPE
  15.  
  16. class Leveller(gst.Pipeline):
  17.     """
  18.     I am a pipeline that calculates RMS values and mix-in/out points.
  19.     I will signal 'done' when I'm done scanning the file, with return value
  20.     EOS, ERROR, UNKNOWN_TYPE, or WRONG_TYPE from gst.extend.sources
  21.     """
  22.     gsignal('done', str)
  23.     
  24.     def __init__(self, filename, threshold = -9):
  25.         gst.Pipeline.__init__(self)
  26.         self._filename = filename
  27.         self._thresholddB = threshold
  28.         self._threshold = math.pow(10, self._thresholddB / 10)
  29.         self._source = sources.AudioSource(filename)
  30.         self._source.connect('done', self._done_cb)
  31.         self._level = gst.element_factory_make('level')
  32.         self._fakesink = gst.element_factory_make('fakesink')
  33.         self.add(self._source, self._level, self._fakesink)
  34.         self._source.connect('pad-added', self._sourcePadAddedCb)
  35.         self._level.link(self._fakesink)
  36.         self._rmsdB = { }
  37.         self._peakdB = 0
  38.         self._meansquaresums = []
  39.         self._peaksdB = []
  40.         self._lasttime = 0
  41.         self.mixin = 0
  42.         self.mixout = 0
  43.         self.length = 0
  44.         self.rms = 0
  45.         self.rmsdB = 0
  46.  
  47.     
  48.     def _sourcePadAddedCb(self, source, pad):
  49.         self._source.link(self._level)
  50.  
  51.     
  52.     def do_handle_message(self, message):
  53.         self.debug('got message %r' % message)
  54.         if message.type == gst.MESSAGE_ELEMENT and message.src == self._level:
  55.             struc = message.structure
  56.             endtime = struc['endtime']
  57.             rmss = struc['rms']
  58.             peaks = struc['peak']
  59.             decays = struc['decay']
  60.             infos = zip(rmss, peaks, decays)
  61.             channid = 0
  62.             for rms, peak, decay in infos:
  63.                 self._level_cb(message.src, endtime, channid, rms, peak, decay)
  64.                 channid += 1
  65.             
  66.         elif message.type == gst.MESSAGE_EOS:
  67.             self._eos_cb(message.src)
  68.         
  69.         gst.Pipeline.do_handle_message(self, message)
  70.  
  71.     
  72.     def _level_cb(self, element, time, channel, rmsdB, peakdB, decaydB):
  73.         if time > self._lasttime and self._lasttime > 0:
  74.             meansquaresum = 0
  75.             for i in self._rmsdB.keys():
  76.                 meansquaresum += math.pow(10, self._rmsdB[i] / 10)
  77.             
  78.             meansquaresum /= len(self._rmsdB.keys())
  79.             
  80.             try:
  81.                 rmsdBstr = str(10 * math.log10(meansquaresum))
  82.             except OverflowError:
  83.                 rmsdBstr = '(-inf)'
  84.  
  85.             gst.log('meansquaresum %f (%s dB)' % (meansquaresum, rmsdBstr))
  86.             self._peaksdB.append((self._lasttime, peakdB))
  87.             self._meansquaresums.append((self._lasttime, meansquaresum))
  88.             self._rmsdB = { }
  89.             self._peakdB = 0
  90.         
  91.         gst.log('time %s, channel %d, rmsdB %f' % (gst.TIME_ARGS(time), channel, rmsdB))
  92.         self._lasttime = time
  93.         self._rmsdB[channel] = rmsdB
  94.         if peakdB > self._peakdB:
  95.             self._peakdB = peakdB
  96.         
  97.  
  98.     
  99.     def _done_cb(self, source, reason):
  100.         gst.debug('done, reason %s' % reason)
  101.         if reason == EOS:
  102.             return None
  103.         self.emit('done', reason)
  104.  
  105.     
  106.     def _eos_cb(self, source):
  107.         gst.debug('eos, start calcing')
  108.         highestdB = self._peaksdB[0][1]
  109.         for time, peakdB in self._peaksdB:
  110.             if peakdB > highestdB:
  111.                 highestdB = peakdB
  112.                 continue
  113.         
  114.         gst.debug('highest peak(dB): %f' % highestdB)
  115.         (self.length, peakdB) = self._peaksdB[-1]
  116.         for time, peakdB in self._peaksdB:
  117.             gst.log('time %s, peakdB %f' % (gst.TIME_ARGS(time), peakdB))
  118.             if peakdB > self._thresholddB + highestdB:
  119.                 gst.debug('found mix-in point of %f dB at %s' % (peakdB, gst.TIME_ARGS(time)))
  120.                 self.mixin = time
  121.                 break
  122.                 continue
  123.         
  124.         self._peaksdB.reverse()
  125.         found = None
  126.         for time, peakdB in self._peaksdB:
  127.             if found:
  128.                 self.mixout = time
  129.                 gst.debug('found mix-out point of %f dB right before %s' % (found, gst.TIME_ARGS(time)))
  130.                 break
  131.             
  132.             if peakdB > self._thresholddB + highestdB:
  133.                 found = peakdB
  134.                 continue
  135.         
  136.         weightedsquaresums = 0
  137.         lasttime = self.mixin
  138.         for time, meansquaresum in self._meansquaresums:
  139.             if time <= self.mixin:
  140.                 continue
  141.             
  142.             delta = time - lasttime
  143.             weightedsquaresums += meansquaresum * delta
  144.             gst.log('added MSS %f over time %s at time %s, now %f' % (meansquaresum, gst.TIME_ARGS(delta), gst.TIME_ARGS(time), weightedsquaresums))
  145.             lasttime = time
  146.             if time > self.mixout:
  147.                 break
  148.                 continue
  149.         
  150.         
  151.         try:
  152.             ms = weightedsquaresums / (self.mixout - self.mixin)
  153.         except ZeroDivisionError:
  154.             gst.warning('ZeroDivisionError on %s, mixin %s, mixout %s' % (self._filename, gst.TIME_ARGS(self.mixin), gst.TIME_ARGS(self.mixout)))
  155.             self.emit('done', WRONG_TYPE)
  156.             return None
  157.  
  158.         self.rms = math.sqrt(ms)
  159.         self.rmsdB = 10 * math.log10(ms)
  160.         self.emit('done', EOS)
  161.  
  162.     
  163.     def start(self):
  164.         gst.debug('Setting to PLAYING')
  165.         self.set_state(gst.STATE_PLAYING)
  166.         gst.debug('Set to PLAYING')
  167.  
  168.     
  169.     def stop(self):
  170.         """
  171.         Stop the leveller, freeing all resources.
  172.         Call after the leveller emitted 'done' to clean up.
  173.         """
  174.         gst.debug('Setting to NULL')
  175.         self.set_state(gst.STATE_NULL)
  176.         gst.debug('Set to NULL')
  177.         utils.gc_collect('Leveller.stop()')
  178.  
  179.     
  180.     def clean(self):
  181.         self.stop()
  182.         self.remove(self._source)
  183.         self.remove(self._level)
  184.         self.remove(self._fakesink)
  185.         gst.debug('Emptied myself')
  186.         self._source.clean()
  187.         utils.gc_collect('Leveller.clean() cleaned up source')
  188.         self._source = None
  189.         self._fakesink = None
  190.         self._level = None
  191.         utils.gc_collect('Leveller.clean() done')
  192.  
  193.  
  194. gobject.type_register(Leveller)
  195. if __name__ == '__main__':
  196.     main = gobject.MainLoop()
  197.     
  198.     try:
  199.         leveller = Leveller(sys.argv[1])
  200.     except IndexError:
  201.         sys.stderr.write('Please give a file to calculate level of\n')
  202.         sys.exit(1)
  203.  
  204.     print 'Starting'
  205.     bus = leveller.get_bus()
  206.     bus.add_signal_watch()
  207.     dontstop = True
  208.     leveller.set_state(gst.STATE_PLAYING)
  209.     while dontstop:
  210.         message = bus.poll(gst.MESSAGE_ANY, gst.SECOND)
  211.         if message:
  212.             gst.debug('got message from poll:%s/%r' % (message.type, message))
  213.         else:
  214.             gst.debug('got NOTHING from poll')
  215.         if message:
  216.             if message.type == gst.MESSAGE_EOS:
  217.                 print 'in: %s, out: %s, length: %s' % (gst.TIME_ARGS(leveller.mixin), gst.TIME_ARGS(leveller.mixout), gst.TIME_ARGS(leveller.length))
  218.                 print 'rms: %f, %f dB' % (leveller.rms, leveller.rmsdB)
  219.                 dontstop = False
  220.             elif message.type == gst.MESSAGE_ERROR:
  221.                 (error, debug) = message.parse_error()
  222.                 print 'ERROR[%s] %s' % (error.domain, error.message)
  223.                 dontstop = False
  224.             
  225.         message.type == gst.MESSAGE_EOS
  226.     leveller.stop()
  227.     leveller.clean()
  228.     gst.debug('deleting leveller, verify objects are freed')
  229.     utils.gc_collect('quit main loop')
  230.     del leveller
  231.     utils.gc_collect('deleted leveller')
  232.     gst.debug('stopping forever')
  233.  
  234.